﻿//-----------------------------------------------------------------------------------------------------------
// WBFSSync Project by Omega Frost 
// http://wbfssync.codeplex.com/
//
// WBFSSync is Licensed under the terms of the 
// Microsoft Reciprocal License (Ms-RL)
//-----------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WBFSe3;
using WBFSe3.IO;
using System.Threading;

namespace WbfsSync.Core
{
    //-------------------------------------------------------------------------------------------------------
    //
    //-------------------------------------------------------------------------------------------------------
    public delegate void DeviceEventHandler(WbfsDriveInfo drive, WbfsError error);


    //-------------------------------------------------------------------------------------------------------
    //
    //-------------------------------------------------------------------------------------------------------
    public static class HotSwap
    {
        //---------------------------------------------------------------------------------------------------
        //
        //---------------------------------------------------------------------------------------------------
        public static event DeviceEventHandler DeviceInserted;
        public static event DeviceEventHandler DeviceRemoved;


        //---------------------------------------------------------------------------------------------------
        //
        //---------------------------------------------------------------------------------------------------
        public static void HandleDeviceEvent(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            Char letter;
            Boolean removed, inserting;
            Native.DEV_BROADCAST_HDR device;
            Native.DEV_BROADCAST_VOLUME volume;

            Native.GetDeviceBroadcast(lParam, out device);
            removed = Native.HasRemovedDevice(wParam.ToInt32());
            inserting = Native.IsInsertingDevice(wParam.ToInt32());

            if (device.IsVolume)
            {
                letter = 'A';
                Native.GetVolumeBroadcast(lParam, out volume);
                while (volume.dbcv_unitmask != 0)
                {
                    if ((volume.dbcv_unitmask & 0x1) != 0)
                    {
                        WbfsError error;
                        WbfsDriveInfo drive;

                        Thread.Sleep(100);

                        error = WbfsDriveInfo.GetDrive(letter + 
                            ":\\", out drive);

                        if (inserting)
                        {
                            if (DeviceInserted != null)
                                DeviceInserted(drive, error);
                        }
                        else if (removed)
                        {
                            if (drive != null)
                                drive.Close();

                            if (DeviceRemoved != null)
                                DeviceRemoved(drive, WbfsError.Ok);
                        }
                    }

                    letter++;
                    volume.dbcv_unitmask >>= 1;
                }
            }
        }
    }
}
